package org.game.graphics;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.game.map.GWField;
import org.game.map.GWMap;
import org.game.obj.GWObject;
import org.game.obj.building.GWCastle;
import org.game.obj.building.GWFarm;
import org.game.obj.building.GWForest;
import org.game.obj.building.GWIronOrePit;
import org.game.obj.unit.GWKnight;
import org.game.obj.unit.GWPeasant;
import org.game.obj.unit.GWSpearman;
import org.game.player.GWPlayer;
import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;

public class GWRenderer implements GWRenderConstants {
	
	private static GWRenderer renderer;
	
	private GWMap map;
	private GWPlayer pl1, pl2;
	
	private static Image castle01, castle02;
	private static Image forest, ironOrePit, farm;
	private static Image grass, water;
	private static Image peasant01, spearman01, knight01;
	private static Image peasant02, spearman02, knight02;
	
	private GWRenderer(GWMap map, GWPlayer pl1, GWPlayer pl2) {
		this.map = map;
		this.pl1 = pl1;
		this.pl2 = pl2;
	}
	
	public static GWRenderer createInstance(GWMap map, GWPlayer pl1, GWPlayer pl2) {
		renderer = new GWRenderer(map, pl1, pl2);
		init();
		return renderer;
	}
	
	public static GWRenderer getInstance() {
		return renderer;
	}
	
	public static void init() {
		try {
			castle01 = new Image("graphics/Castle01.png");
			castle02 = new Image("graphics/Castle02.png");
			
			forest = new Image("graphics/Forest.png");
			farm = new Image("graphics/Farm.png");
			ironOrePit = new Image("graphics/IronOrePit.png");
			grass = new Image("graphics/Grass.png");
			
			peasant01 = new Image("graphics/Peasant01.png");
			spearman01 = new Image("graphics/Spearman01.png");
			knight01 = new Image("graphics/Knight01.png");
			
			peasant02 = new Image("graphics/Peasant02.png");
			spearman02 = new Image("graphics/Spearman02.png");
			knight02 = new Image("graphics/Knight02.png");
		} catch (SlickException e) {
			throw new RuntimeException(e);
		}
	}
	
	public void draw(Graphics g) {
		drawFields(g);
		drawObjects(g);
		drawScores(g);
	}
	
	private void drawFields(Graphics g) {
		float fx = 0;
		float fy = 0;
		
		for(int x = 0; x < map.getSizeX(); x++) {
			for(int y = 0; y < map.getSizeY(); y++) {
				switch(map.getField(x, y).getType()) {
				case GWField.GRASS:
					g.setColor(new Color(0, 100, 10));
					break;
				case GWField.WATER:
					g.setColor(new Color(0, 30, 150));
					break;
				}
				g.drawImage(grass, fx, fy);
				fy += FIELD_SIZE;
			}
			fx += FIELD_SIZE;
			fy = 0;
		}
	}
	
	private void drawObjects(Graphics g) {
		
		List<GWObject> list = new ArrayList<GWObject>();
		for(int x = 0; x < map.getSizeX(); x++) {
			for(int y = 0; y < map.getSizeY(); y++) {
				GWObject obj = map.getField(x, y).getObject();
				if(obj != null && !list.contains(obj)) {
					list.add(obj);
				}
			}
		}
		
		Collections.sort(list, new SortByY());
		
		float fx = 0;
		float fy = 0;
		float fw = 0;
		float fh = 0;
		
		Iterator<GWObject> it = list.iterator();
		while(it.hasNext()) {
			GWObject obj = it.next();
			if(obj instanceof GWPeasant) {
				fx = obj.getX() * FIELD_SIZE - 5;
				fy = obj.getY() * FIELD_SIZE - 10;
				if(obj.getPlayer() == 1) { 
					g.drawImage(peasant01, fx, fy);
				} else {
					g.drawImage(peasant02, fx, fy);
				}
			}
			else if(obj instanceof GWSpearman) {
				fx = obj.getX() * FIELD_SIZE - 5;
				fy = obj.getY() * FIELD_SIZE - 10;
				if(obj.getPlayer() == 1) { 
					g.drawImage(spearman01, fx, fy);
				} else {
					g.drawImage(spearman02, fx, fy);
				}
			}
			else if(obj instanceof GWKnight) {
				fx = obj.getX() * FIELD_SIZE - 5;
				fy = obj.getY() * FIELD_SIZE - 10;
				if(obj.getPlayer() == 1) { 
					g.drawImage(knight01, fx, fy);
				} else {
					g.drawImage(knight02, fx, fy);
				}
			}
			else if(obj instanceof GWForest) {
				fx = obj.getX() * FIELD_SIZE;
				fy = obj.getY() * FIELD_SIZE - 20;
				g.drawImage(forest, fx, fy);
			}
			else if(obj instanceof GWFarm) {
				fx = obj.getX() * FIELD_SIZE;
				fy = obj.getY() * FIELD_SIZE - 20;
				g.drawImage(farm, fx, fy);
			}
			else if(obj instanceof GWIronOrePit) {
				fx = obj.getX() * FIELD_SIZE;
				fy = obj.getY() * FIELD_SIZE;
				g.drawImage(ironOrePit, fx, fy);
			}
			else if(obj instanceof GWCastle) {
				fx = obj.getX() * FIELD_SIZE;
				fy = obj.getY() * FIELD_SIZE - 20;
				if(obj.getPlayer() == 1) {
					g.drawImage(castle01, fx, fy);
				} else {
					g.drawImage(castle02, fx, fy);
				}
			} else {
				fx = obj.getX() * FIELD_SIZE;
				fy = obj.getY() * FIELD_SIZE;
				fw = obj.getWidth() * FIELD_SIZE;
				fh = obj.getHeight() * FIELD_SIZE;
				switch(obj.getPlayer()) {
				case 0:
					g.setColor(new Color(100, 100, 100));
					break;
				case 1:
					g.setColor(new Color(200, 0, 0));
					break;
				case 2:
					g.setColor(new Color(0, 0, 200));
					break;
				}
	//			if(obj instanceof GWPeasant && ((GWPeasant) obj).isLoaded()) {
	//				g.setColor(new Color(100, 100, 100));
	//			} else {
	//				g.setColor(new Color(200, 0, 0));
	//			}
				g.fillOval(fx, fy, fw, fh);
			}
		}
	}
	
	private void drawScores(Graphics g) {
		g.drawString(""+pl1.getFood(), 100, 711);
		g.drawString(""+pl1.getWood(), 200, 711);
		g.drawString(""+pl1.getSteel(), 300, 711);
		g.drawString(""+pl1.getKills(), 400, 711);
		
		g.drawString(""+pl2.getFood(), 600, 711);
		g.drawString(""+pl2.getWood(), 700, 711);
		g.drawString(""+pl2.getSteel(), 800, 711);
		g.drawString(""+pl2.getKills(), 900, 711);
	}
}
